import csv
from PySide2.QtWidgets import (QWidget, QTableWidget, QTableWidgetItem, QPushButton, QVBoxLayout, QHBoxLayout,
                               QHeaderView, QLabel, QLineEdit)
from PySide2.QtCore import Qt
from business.business3 import TrueInclinationCalculator

from .form.widget_simple_ui import Ui_formSimple as FormSimple


class WidgetAngle(QWidget, FormSimple):
    def __init__(self):
        super().__init__()
        self.setupUi(self)
        self.labelTitleSimple.setText('真倾角转视倾角程序')
        self.labelTitleSimple.setStyleSheet('font-size:16pt; font-weight:600;')

        # region 初始化中央部件
        central_widget = QWidget()
        main_layout = QVBoxLayout(central_widget)  # 主布局使用垂直布局
        main_layout.setContentsMargins(10, 10, 10, 10)  # 布局边距(左, 上, 右, 下)
        main_layout.setSpacing(15)  # 控件间距
        main_layout = QVBoxLayout(self.widgetSimple)
        main_layout.addWidget(central_widget)
        # endregion

        # ==================== 功能控件区 ====================
        # region 操作按钮组
        btn_layout = QHBoxLayout()
        # 导入CSV按钮
        self.import_btn = QPushButton("导入CSV数据", self)
        self.import_btn.setToolTip("支持格式：UTF-8编码的CSV文件")  # 鼠标悬停提示
        self.import_btn.clicked.connect(self.import_csv)  # 绑定点击事件
        btn_layout.addWidget(self.import_btn)

        # 添加行按钮
        self.add_row_btn = QPushButton("添加新行", self)
        self.add_row_btn.setToolTip("在表格末尾添加新数据行")
        self.add_row_btn.clicked.connect(self.add_new_row)
        btn_layout.addWidget(self.add_row_btn)

        main_layout.addLayout(btn_layout)  # 将按钮组加入主布局
        # endregion

        # region 批量修改组件
        h_layout = QHBoxLayout()
        # 批量修改标签
        self.batch_edit_label = QLabel("批量修改第四列数据:")
        # 输入框
        self.batch_edit_input = QLineEdit()
        self.batch_edit_input.setPlaceholderText("输入井轨边方位值")  # 占位提示文本
        # 应用按钮
        self.apply_batch_btn = QPushButton("应用")
        self.apply_batch_btn.clicked.connect(self.apply_batch_update)

        h_layout.addWidget(self.batch_edit_label)
        h_layout.addWidget(self.batch_edit_input)
        h_layout.addWidget(self.apply_batch_btn)
        main_layout.addLayout(h_layout)
        # endregion

        # ==================== 数据表格区 ====================
        self.table = QTableWidget()
        main_layout.addWidget(self.table)
        self._initialize_table()  # 初始化表格结构
        self.table.cellChanged.connect(self._handle_cell_change)  # 单元格变更事件绑定

    def _initialize_table(self):
        """初始化表格结构和表头"""
        # 表格维度设置
        self.table.setColumnCount(5)  # 5列：4输入+1结果
        self.table.setRowCount(3)  # 3行：标题行+单位行+1数据行

        # region 表头设置
        # 合并单元格（起始行，起始列，合并行数，合并列数）
        self.table.setSpan(0, 0, 1, 4)  # 合并前四列为"输入参数"

        # 设置表头单元格
        self._set_header_cell(0, 0, "输入参数", "地层参数输入区域")
        self._set_header_cell(0, 4, "计算结果", "视倾角计算结果")

        # 列标题
        column_titles = ["深度", "地层真倾向", "地层真倾角", "井轨边方位", "沿井轨迹视倾角"]
        for col, title in enumerate(column_titles):
            self._set_header_cell(1, col, title, "数据列标题")

        # 单位说明
        units = ["m", "deg", "deg", "deg", "deg"]
        for col, unit in enumerate(units):
            self._set_header_cell(2, col, unit, "测量单位")

        # 锁定表头编辑
        for row in range(3):
            for col in range(5):
                if item := self.table.item(row, col):
                    item.setFlags(item.flags() & ~Qt.ItemIsEditable)  # 移除可编辑标志
        # endregion

        # 表格显示设置
        self.table.horizontalHeader().setSectionResizeMode(QHeaderView.Stretch)  # 自动拉伸列宽
        self.table.verticalHeader().setDefaultSectionSize(30)  # 行高

    def _set_header_cell(self, row, col, text, tooltip=""):
        """辅助方法：设置表头单元格
        Args:
            row: 行索引
            col: 列索引
            text: 显示文本
            tooltip: 悬停提示信息
        """
        item = QTableWidgetItem(text)
        item.setTextAlignment(Qt.AlignCenter)  # 居中对齐
        item.setToolTip(tooltip)  # 提示信息
        self.table.setItem(row, col, item)

    def _handle_cell_change(self, row, column):
        """处理单元格内容变更事件
        触发条件：数据行（row>=3）的前四列（0-3列）内容变化
        """
        if column > 3 or row < 3:  # 仅处理数据行的前四列
            return

        # 临时断开信号防止递归触发
        self.table.cellChanged.disconnect(self._handle_cell_change)
        try:
            self._update_calculation_results([row])  # 更新当前行计算结果
        finally:
            self.table.cellChanged.connect(self._handle_cell_change)  # 重新连接

    def _update_calculation_results(self, rows):
        """批量更新计算结果
        Args:
            rows: 需要更新的行号列表（基于0的索引）
        """
        for r in rows:
            try:
                # 获取输入参数（深度、真倾向、真倾角、井轨方位）
                input_params = [
                    self._get_numeric_cell_value(r, 0),
                    self._get_numeric_cell_value(r, 1),
                    self._get_numeric_cell_value(r, 2),
                    self._get_numeric_cell_value(r, 3)
                ]
                # 调用计算模块（保留9位小数）
                result = TrueInclinationCalculator.calculate_view_inclination(*input_params)
                result_text = f"{result:.9f}"
            except (ValueError, TypeError):  # 数值转换失败
                result_text = "无效输入"
            except AttributeError:  # 单元格不存在
                result_text = "数据缺失"

            # 设置结果单元格
            result_item = QTableWidgetItem(result_text)
            result_item.setTextAlignment(Qt.AlignCenter)
            result_item.setFlags(result_item.flags() & ~Qt.ItemIsEditable)  # 禁止编辑
            self.table.setItem(r, 4, result_item)

    def _get_numeric_cell_value(self, row, column):
        """获取单元格数值
        Returns:
            float: 单元格数值
        Raises:
            AttributeError: 单元格不存在
            ValueError: 非数值内容
        """
        if cell := self.table.item(row, column):
            return float(cell.text())
        raise AttributeError(f"单元格({row},{column})不存在")

    def apply_batch_update(self):
        """批量更新第四列数据"""
        new_value = self.batch_edit_input.text()

        # 输入验证
        try:
            float(new_value)  # 确保输入为有效数字
        except ValueError:
            return  # 无效输入静默失败

        # 批量更新流程
        self.table.cellChanged.disconnect(self._handle_cell_change)  # 暂停事件监听
        try:
            for row in range(3, self.table.rowCount()):  # 从第4行开始（索引3）
                item = self.table.item(row, 3) or QTableWidgetItem()  # 获取或新建单元格
                item.setTextAlignment(Qt.AlignCenter)
                item.setText(new_value)
                self.table.setItem(row, 3, item)
        finally:
            self.table.cellChanged.connect(self._handle_cell_change)  # 恢复监听

        # 触发结果更新
        self._update_calculation_results(range(3, self.table.rowCount()))

    def add_new_row(self):
        """添加新数据行"""
        current_row_count = self.table.rowCount()
        self.table.setRowCount(current_row_count + 1)  # 扩展行数

        # 初始化输入列（0-3列）
        for col in range(4):
            item = QTableWidgetItem("0.0")  # 默认值
            item.setTextAlignment(Qt.AlignCenter)
            self.table.setItem(current_row_count, col, item)

        # 初始化结果列（4列）
        result_item = QTableWidgetItem("")
        result_item.setTextAlignment(Qt.AlignCenter)
        result_item.setFlags(result_item.flags() & ~Qt.ItemIsEditable)
        self.table.setItem(current_row_count, 4, result_item)

        # 自动计算新行
        self._update_calculation_results([current_row_count])

    def import_csv(self):
        """处理CSV文件导入"""
        from PySide2.QtWidgets import QFileDialog

        # 文件选择对话框
        csv_file, _ = QFileDialog.getOpenFileName(
            parent=self,
            caption="选择测量数据文件",
            filter="CSV文件 (*.csv);;所有文件 (*)",
            options=QFileDialog.DontUseNativeDialog  # 强制使用Qt对话框
        )
        if not csv_file:
            return  # 用户取消选择

        try:
            # 读取并过滤空行
            with open(csv_file, 'r', encoding='utf-8-sig') as f:  # 处理BOM头
                raw_data = csv.reader(f)
                valid_rows = [row for row in raw_data if any(field.strip() for field in row)]

            if not valid_rows:
                raise ValueError("CSV文件内容为空")
        except Exception as e:
            print(f"[错误] 文件读取失败：{str(e)}")
            return

        # 清空现有数据（保留3行表头）
        self.table.setRowCount(3 + len(valid_rows))

        # 填充数据
        for row_idx, csv_row in enumerate(valid_rows):
            table_row = 3 + row_idx  # 数据从第4行开始

            # 填充前四列
            for col in range(4):
                value = csv_row[col].strip() if col < len(csv_row) else ""
                cell = QTableWidgetItem(value)
                cell.setTextAlignment(Qt.AlignCenter)
                self.table.setItem(table_row, col, cell)

            # 计算结果列
            try:
                params = [float(csv_row[i]) for i in range(4)]  # 前四列转为float
                result = TrueInclinationCalculator.calculate_view_inclination(*params)
                result_text = f"{result:.9f}"  # 结果保留9位小数
            except (IndexError, ValueError, TypeError):  # 数据不完整或格式错误
                result_text = ""

            # 设置结果单元格
            result_cell = QTableWidgetItem(result_text)
            result_cell.setTextAlignment(Qt.AlignCenter)
            result_cell.setFlags(result_cell.flags() & ~Qt.ItemIsEditable)
            self.table.setItem(table_row, 4, result_cell)
